package com.quyang.voice.utils;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.quyang.voice.token.html.EscapeUtil;
import eu.bitwalker.useragentutils.Browser;
import eu.bitwalker.useragentutils.UserAgent;
import org.apache.commons.lang3.RandomStringUtils;
import org.lionsoul.ip2region.DataBlock;
import org.lionsoul.ip2region.DbConfig;
import org.lionsoul.ip2region.DbSearcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.DecimalFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Pattern;

public class StringUtils {


    private static Logger _logger = LoggerFactory.getLogger(StringUtils.class);
	private static boolean ipLocal = false;
	private static final String UNKNOWN = "unknown";
	//全国省份
	public static final String[] list_province = {"安徽", "北京", "福建", "甘肃", "广东",
											"广西", "贵州", "海南", "河北", "河南", "黑龙江", "湖北", "湖南", "吉林", "江苏", "江西",
											"辽宁", "内蒙古", "宁夏", "青海", "山东", "山西", "陕西", "上海", "四川", "天津", "西藏",
											"新疆", "云南", "浙江", "重庆", "香港", "澳门", "台湾", "其它" };
	//非标资产所有Type
	public static final String[] ns_arrays = new String[]{"4", "5", "6", "7", "10", "11", "12", "13", "14", "15"};
	private static File file = null;
	private static DbConfig config;
	/**
	 * 把一个字符串分割成一个int[]
	 *
	 * @param str
	 * @param sign
	 *            各个标准
	 * @return
	 */
	public final static int[] strToIntArray(String str,String sign){
		if(StringUtils.isBlank(str) || sign == null){
			return null;
		}
		String[] vals = str.split(sign);
		int size = vals.length;
		int[] data = new int[size];
		for (int i = 0; i < size; i++) {
			String val = vals[i];
			if (StringUtils.isNotBlank(val)) {
				data[i] = Integer.valueOf(val.trim());
			}
		}
		return data;
	}

	/*四舍五入转int*/
	public static int floatToInt(float f) {
		int i = 0;
		if (f > 0) //正数
			i = (int) ((f * 10 + 5) / 10);
		else if (f < 0) //负数
			i = (int) ((f * 10 - 5) / 10);
		else i = 0;

		return i;

	}


	public static boolean checkParametersIsNotNull(String... parameters) {
		boolean result = true;
		for (String value : parameters) {
			if (StringUtils.isBlank(value)) {
				result = false;
				break;
			}
		}
        return result;
    }

	/**
	 * 把一个字符串分割成一个List<Integer>
	 *
	 * @param str
	 * @param sign
	 *            各个标准
	 * @return
	 */
	public final static List<Integer> strToIntList(String str,String sign){
		if(StringUtils.isBlank(str) || sign == null){
			return null;
		}
		String[] vals = str.split(sign);
		int size = vals.length;
		List<Integer> data = new ArrayList<Integer>();
		for(int i = 0;i < size;i++){
			String val = vals[i];
			if(StringUtils.isNotBlank(val)){
				data.add(Integer.valueOf(val.trim()));
			}
		}
		return data;
	}

	/**
	 * 把一个字符串分割成一个List<String>
	 *
	 * @param str
	 * @param sign
	 *            各个标准
	 * @return
	 */
	public final static List<String> strToStringList(String str,String sign){
		if(StringUtils.isBlank(str) || sign == null){
			return null;
		}
		String[] vals = str.split(sign);
		int size = vals.length;
		List<String> data = new ArrayList<String>();
		for(int i = 0;i < size;i++){
			String val = vals[i];
			if(StringUtils.isNotBlank(val)){
				data.add(val.trim());
			}
		}
		return data;
	}

	/**
	 * 是否为null
	 *
	 * @param str
	 * @return
	 */
	public static boolean isNull(String str){
		if(str == null){
			return true;
		}
		return false;
	}

	/**
	 * 不为null
	 *
	 * @param str
	 * @return
	 */
	public static boolean isNotNull(String str){
		return !StringUtils.isNull(str);
	}

	/**
	 * String[] 是否为null
	 *
	 * @param str
	 * @return
	 */
	public static boolean arrayISNull(String[] str){
		if(null == str || str.length==0){
			return true;
		}
		return false;
	}

	/**
	 * 是否为空
	 *
	 * @param str
	 * @return
	 */
	public static boolean isBlank(String str){
		if(!StringUtils.isNull(str) && !"".equals(str.trim())){
			return false;
		}
		return true;
	}

	/**
	 * 不为空
	 *
	 * @param str
	 * @return
	 */
	public static boolean isNotBlank(String str){
		return !StringUtils.isBlank(str);
	}

	/**
	 * 取得UUID
	 * @return
	 */
	public static String getUUID()
	{
		return UUID.randomUUID().toString();
	}

	public static boolean isEmpty(Object str) {
		return (null == str || "".equals(str));
	}

	 /**
     * 从默认字符串数据组中从第from个起，取count个值至新的字符数组中，并保证第一个值为value.
     * @param value
     * @param ids
     * @param start
     * @param count
     * @return
     */
    public static StringBuilder addStringOnTop(String value, String[] ids, int start, int count) {


        StringBuilder sb = new StringBuilder();

        int max = start + count;

        if (start < 0 || count < 0) {
            _logger.error("the start or count value can't less than 0. [{}/{}]", start, count);
            return sb;
        }

        if (ids.length+1 < max ) {
            _logger.error("the total strings [{}] is less than max[{}] value :{}", ids.length, max);
            return sb;
        }

        int i = 0;
        if (StringUtils.isNotBlank(value)) {
            sb.append(value);
            i++;
        }

        int m = 0;

        for (String id : ids) {
            if ( m >= start) {
                if (count ==0 || m <= max) {
                    if (i > 0)
                        sb.append(",");
                    sb.append(id);
                    i++;
                }
            }
            m++;
        }
        return sb;
    }

    /**
     * 字体串数组转
     * @param values
     * @param separator
     * @return
     */
    public static String strArrayToStringWithSeperator(String[] values, String separator) {
        StringBuilder sb = new StringBuilder();
        int i = 0;
        for (String value : values) {
            if (i > 0)
                sb.append(",");

            sb.append(value);
            i++;
        }
        return sb.toString();
    }

    /**
     * 字体串数组转
     * separator 以特定符号拼接,例如 ',那么返回的则为 '1','2','3'
     * @param values
     * @param separator
     * @return
     */
    public static String strArrayToStr(String[] values, String separator) {
        StringBuilder sb = new StringBuilder();
        int i = 0;
        for (String value : values) {
            if (i > 0)
                sb.append(",");
            sb.append(separator).append(value).append(separator);
            i++;
        }
        return sb.toString();
    }


    /**
     * 从一个字符串里分离出连续的一部分
     * @param value
     * @param start
     * @param count
     * @param separator
     * @return
     */
    public static String separateOutString(String value, int start, int count, String separator) {


        /**
         * 如果记录数取0，则返回全部数据
         */
        if (count == 0) {
            return  value;
        }

        String result = "";

        String[] ids = value.split(separator);
        int length = ids.length;
        int total = start + count;

        if (length > start) {

            if (length > total) {

                int m=0;
                for (int i=start; i<total; i++) {
                    if (m<count) {
                        if (i > start)
                            result = result + separator;
                        result = result + ids[i];
                    }
                    m++;
                }

            } else {
                for (int i=start; i<length; i++) {
                    if (i>start)
                        result = result + separator;
                    result = result + ids[i];
                }
            }
        }
        return result;
    }

	public static boolean isNumeric(String str) {
		for (int i = str.length(); --i >= 0;) {
			if (!Character.isDigit(str.charAt(i))) {
				return false;
			}
		}
		return true;
	}

	/**
	 * 获取六位随机码
	 * @return
	 */
	public static String RandomNumber(){
		int[] array = {0,1,2,3,4,5,6,7,8,9};
		Random rand = new Random();
		for (int i = 10; i > 1; i--) {
			//将数组下标随机排列
		    int index = rand.nextInt(i);
		    int tmp = array[index];
		    array[index] = array[i - 1];
		    array[i - 1] = tmp;
		}
		StringBuffer sb = new StringBuffer();
		//循环取出六位数
		for(int i = 0; i < 6;i++){
			sb.append(array[i]);
		}
		return sb.toString();
	}

	/**
	 * 将手机号中间四位替换成*（150****3065）
	 * @param mobile
	 * @return
	 */
	public static String mobileSub(String mobile){
		if("11".equals(mobile.length()+"")){
			String start = mobile.substring(0, 3);
			String end = mobile.substring(7, mobile.length());
			return start+"****"+end;
		}
		return null;
	}

	/**
	 * 去掉字符串中斜杠和中括号
	 * @param str
	 * @return
	 */
	public static String stringRep(String str){
		if(null!=str && !"".equals(str)){
			str = str.replaceAll("\\[","");
			str = str.replaceAll("\\]","");
			str = str.replaceAll("\"","");
			return str;
		}
		return null;
	}

	public static String stringRep2(String str){
		if(null!=str && !"".equals(str)){
			str = str.replaceAll("\"","");
			return str;
		}
		return null;
	}

	/**
	 * 截取字符串中“.”右边的值
	 * @param ob
	 * @return
	 */
	public static String stringFilterSpit(Object ob){
		String str = null;
		if(null!=ob){
			str = ob.toString();
			int index = str.lastIndexOf(".");
			str = str.substring(index+1, str.length());
		}
		return str;

	}

	/**
	 * 判断是否为数字
	 * @param str
	 * @return
	 */
	public static boolean stringPattern(String str){
		Pattern pattern = Pattern.compile("[0-9]*");
		return pattern.matcher(str).matches();
	}


	/**
	 * 将金钱单位转换成（亿）
	 * @param num
	 * @return
	 */
	public static String moneyFormat(Long num){
		DecimalFormat  df   = new DecimalFormat("#0.00");
		double n = (double)num/10000;
		return df.format(n);
	}

	public static String dmacctSplit(String dmacct) {
		//判断账号中是否有“@”符号
		String[] u = dmacct.split("@");
		if(u.length  > 1){
			//如果有，取“@”前面的字符
			dmacct = u[0];
		}
		return dmacct;
	}

	//判断是否是非标资产,传参
	public static boolean isNonstandardAssets(String[] array, String targetValue) {
		return Arrays.asList(array).contains(targetValue);
	}

	//判断是否是非标资产,不用传参
	public static boolean isNonstandardAssets(String targetValue) {
		return Arrays.asList(ns_arrays).contains(targetValue);
	}

	/**
	 * 生成邀请码
	 *
	 * @param length
	 * @return
	 */
	public static String getInviteCode(int length) {
		String val = "";

		Random random = new Random();
		for (int i = 0; i < length; i++) {
			String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num"; // 输出字母还是数字

			if ("char".equalsIgnoreCase(charOrNum)) // 字符串
			{
				int choice = random.nextInt(2) % 2 == 0 ? 65 : 97; //取得大写字母还是小写字母
				val += (char) (choice + random.nextInt(26));
			} else if ("num".equalsIgnoreCase(charOrNum)) // 数字
			{
				val += String.valueOf(random.nextInt(10));
			}
		}

		return val;
	}

	/**
	 * 根据ip获取详细地址
	 */
	public static String getLocalCityInfo(String ip) {
		try {
			DataBlock dataBlock = new DbSearcher(config, file.getPath())
					.binarySearch(ip);
			String region = dataBlock.getRegion();
			String address = region.replace("0|", "");
			char symbol = '|';
			if (address.charAt(address.length() - 1) == symbol) {
				address = address.substring(0, address.length() - 1);
			}
			return address.equals(Constant.REGION) ? "内网IP" : address;
		} catch (Exception e) {
			_logger.error(e.getMessage(), e);
		}
		return "";
	}
	/**
	 * 根据ip获取详细地址
	 */
	public static String getCityInfo(String ip) {
		if (ipLocal) {
			return getLocalCityInfo(ip);
		} else {
			return getHttpCityInfo(ip);
		}
	}


	/**
	 * 根据ip获取详细地址
	 */
	public static String getHttpCityInfo(String ip) {
		String api = String.format(Constant.Url.IP_URL, ip);
		JSONObject object = JSONUtil.parseObj(HttpUtil.get(api));
		return object.get("addr", String.class);
	}


	public static String getBrowser(HttpServletRequest request) {
		UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
		Browser browser = userAgent.getBrowser();
		return browser.getName();
	}

	/**
	 * 获取ip地址
	 */
	public static String getIp(HttpServletRequest request) {
		String ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		String comma = ",";
		ip = "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
		String localhost = "127.0.0.1";
		if (ip.contains(comma)) {
			ip = ip.split(",")[0];
		}
		if (localhost.equals(ip)) {
			// 获取本机真正的ip地址
			try {
				ip = InetAddress.getLocalHost().getHostAddress();
			} catch (UnknownHostException e) {
				_logger.error(e.getMessage(), e);
			}
		}
		return ip;
	}

	public static String getIpAddr(HttpServletRequest request)
	{
		if (request == null)
		{
			return "unknown";
		}
		String ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
		{
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
		{
			ip = request.getHeader("X-Forwarded-For");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
		{
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
		{
			ip = request.getHeader("X-Real-IP");
		}

		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
		{
			ip = request.getRemoteAddr();
		}
		return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : EscapeUtil.clean(ip);
	}

	/**
	 * 根据参数名称对参数进行字典排序
	 * @param params
	 * @return
	 */
	public static String sortParams(SortedMap<String, String> params) {
		StringBuffer sb = new StringBuffer();
		Set<Map.Entry<String, String>> es = params.entrySet();
		Iterator<Map.Entry<String, String>> it = es.iterator();
		while (it.hasNext()) {
			Map.Entry<String, String> entry = it.next();
			String k = entry.getKey();
			String v = entry.getValue();
			sb.append(k + "=" + v + "&");
		}
		return sb.substring(0, sb.lastIndexOf("&"));
	}



	public static String generateOrderNumber(){

		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
		String format = LocalDateTime.now().format(dateTimeFormatter);

		String numeric = RandomStringUtils.randomNumeric(8);


		return format +  numeric;

	}



	public static void main(String[] args) {

		String str ="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36 Edg/95.0.1020.40";
		UserAgent userAgent = UserAgent.parseUserAgentString(str);

		System.out.println(userAgent.getBrowser().getName());
//		String[] strs = new String[]{"1","2","3"};
//
//		System.out.println(strArrayToStringWithSeperator(strs, ","));z
	}

}
